﻿import numpy as np   
import matplotlib.pyplot as plt   
import torch   
import torch.nn as nn   
import torch.optim as optim
   
# 定义输入数据和标签   
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=np.float32)   
y = np.array([0, 1, 1, 0], dtype=np.float32)
   
# 转换为 PyTorch 张量   
X_tensor = torch.from_numpy(X)   
y_tensor = torch.from_numpy(y).view(-1, 1)
   
# 定义多层感知机模型   
class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.hidden = nn.Linear(2, 2)
        self.output = nn.Linear(2, 1)
    
    def forward(self, x):
        x = torch.relu(self.hidden(x))
        x = torch.sigmoid(self.output(x))
        return x
   
# 初始化模型、损失函数和优化器   
model = MLP()   
criterion = nn.BCELoss()   
optimizer = optim.Adam(model.parameters(), lr=0.1)
   
# 设置绘图   
fig, axes = plt.subplots(2, 5, figsize=(15, 6))   
axes = axes.flatten()
   
# 训练模型并逐步绘制决策边界   
for epoch in range(10):
    # 前向传播
    outputs = model(X_tensor)
    loss = criterion(outputs, y_tensor)
    
    # 反向传播和优化
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    # 绘制决策边界
    xx, yy = np.meshgrid(np.linspace(-0.5, 1.5, 100), np.linspace(-0.5, 1.5, 100))
    grid = np.c_[xx.ravel(), yy.ravel()]
    grid_tensor = torch.from_numpy(grid).float()
    Z = model(grid_tensor).detach().numpy().reshape(xx.shape)
    
    # 绘制决策边界和样本点
    axes[epoch].contourf(xx, yy, Z, alpha=0.8, cmap=plt.cm.coolwarm)
    axes[epoch].scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o', cmap=plt.cm.coolwarm, s=100)
    axes[epoch].set_title(f"Epoch {epoch+1}\nLoss: {loss.item():.2f}")
    axes[epoch].set_xlim(-0.5, 1.5)
    axes[epoch].set_ylim(-0.5, 1.5)
    axes[epoch].set_xticks(())
    axes[epoch].set_yticks(())
   
plt.tight_layout()   
plt.show()
